<?php
class Arm_Translate_Sql_Pdo_Mysql extends Arm_Db_Sql_Mysql
{
    /**
     * Таблица содержащия информацию про текущии языки.
     * @var string
     */
    const ADMIN_LANGS = 'admin_langs';
    /**
     * Префикс к таблицам с переводами
     * @var string
     */
    private $_prefix_translate = '_translate';
    /**
     * Вернет данные с системной языковой таюлици
     * 
     * @return array
     */
    public function getLanguages ()
    {
        $select = $this->_db->select();
        $select->from(self::ADMIN_LANGS);
        return $this->_db->fetchAll($select);
    }
    /**
     * Вставка данных в языковую таблицу, языковая таблица определяеться по названию
     * базовой таблици плюс _translate
     * 
     * @param string $tableBase главная таблица к которой привязываеться таблица 
     * с переводами  через $idNode
     * @param int    $idNode id елемената в гланой таблице к которому привязываеться 
     * перевод. обычно это PRIMARY ключ главной таблицы
     *
     * @param array $data данные которые нужно записать в таблицу перевода
     * это масив array('столбец'=>значение)
     * @param string $lang   язык для которого записываеться значения с $dataInsert
     * Если null будет записан на язык по умолчанию. 
     * @return int id записаного перевода.                             
     */
    public function insertTranslate ($tableBase, $idNode, array $data, $lang = null)
    {
        $tt = $tableBase . $this->_prefix_translate;
        // проверим есть ли таблица в базе данных
        if (false === $this->_isTable($tt)) {
            throw new Arm_Db_Exception(Arm_Translate::_('Не существует таблици "%s"', $tt));
        }
        if ($lang === null) {
            $lang = Arm_Translate::getInstance()->getLanguageDefault();
        }
        $dataInsert = $this->_getArrayColumTable($tt, $data);
        if($dataInsert === array()) {
            return false;
        }
        $dataInsert['id_lang'] = Arm_Translate::getInstance()->getIdLang($lang);
        $dataInsert['id_node_translate'] = $idNode;
        $this->_db->insert($tt, $dataInsert);
        return $this->_db->lastInsertId($tt);
    }
        
    /**
     * Присоединит в запросе к таюлице $tableBase  таблицу с переводами, связь сториться 
     * на основе столбца $idColumnName (его названия) с главной таблици, и столбца таблици
     * переводов  id_node_translate. Если перевода нету для текущего языка, возвращаються
     * данные для языка по умолчанию.
     * 
     * @param string $tableBase навазния базовой таблицы
     * @param string $idColumnName столбец с id которому привязываеться таблица с переводами
     * @param Zend_Db_Select|null $select Если указан объект он будет дополнен соотвествующими частями запроса.
     * @param string|null $lang язык для которого нужно получить переводы, если null будет подучен перевод для текущего языка
     * @return Zend_Db_Select
     */
    public function getSelectTranslate ($tableBase, $idColumnName, Zend_Db_Select $select=null, $lang = null)
    {
        $tt = $tableBase . $this->_prefix_translate;
          
        if ($lang === null) {
            $lang = Arm_Translate::getInstance()->getLanguage();
        }

        $idLang = (int)Arm_Translate::getInstance()->getIdLang($lang);
        $idLangDefault = (int)Arm_Translate::getInstance()->getIdLangDefault();
        
        // строим новый select если не получили его при вызове текущего метода
        if($select === null) {
            $select = $this->_getSelect();
            $select->from($tableBase);
            // дальше строим на основе того - язык указанный являеться языком по умолчанию, или нет. 
        }
        
        // Если запрашиваемый язык совпадает с языком по умолчанию.
        if($idLang === $idLangDefault) {
            $select->join($tt, "$tableBase.$idColumnName=$tt.id_node_translate");
            $select->where($tt . '.id_lang = ?', $idLang);
            return $select;
        }
       
      // нужно получить все столбцы в языковой таблице
      $columns = $this->_getColumnTable($tt);
      foreach ($columns as $k => $v) {
          $columns[$k] = 'COALESCE(arm_this_lang.' . $v. ', arm_default_lang.' . $v . ') as ' . $v . ' ';   
      } 
     
     $select->columns(new Zend_Db_Expr(implode(',', $columns)));
     $select->joinLeft(array('arm_this_lang'=>$tt), "$tableBase.$idColumnName = arm_this_lang.id_node_translate and arm_this_lang.id_lang = $idLang", array());
     $select->joinLeft(array('arm_default_lang'=>$tt), "$tableBase.$idColumnName = arm_default_lang.id_node_translate and arm_default_lang.id_lang = $idLangDefault", array());
     return $select;
    }
    
    /**
     * Удаления данных с языковой таблицы, если $lang не указан будут удалены все 
     * переводы елемента $idNode.
     * @param string $tableBase базовая таблица
     * @param int|array $idNode мисив id или один id елемента(ов ) которые нужно удалить
     * @param string|null $lang переводы с какого языка нужно удалить если null удаляеться все переводы.
     * @return void
     */
    public function deleteTranslate ($tableBase, $idNode, $lang = null)
    {
        $tt = $tableBase . $this->_prefix_translate;
        $idNode = (array) $idNode;
        $where = $this->getDb()->quoteInto('id_node_translate in(?)', $idNode);
        if ($lang !== null) {
            $idLang = Arm_Translate::getInstance()->getIdLang($lang);
            $where .= $this->getDb()->quoteInto(' and id_lang=?', $idLang);
        }
        $this->getDb()->delete($tt, $where);
        return;
    }
    
    /**
     * Вернет имя таблици с переводами на основе имени безовай таблици
     * @param string $tableBase
     * @return string
     */
    public function getNameTableTranslate($tableBase)
    {
     return $tableBase . $this->_prefix_translate;
    }
    
    /**
     * Обносления данных в таблице с переводами, данные по умолчанию обновляються по текущему языку
     * если не уазан язык в параметре $lang
     * @param string $tableBase базовая таблица
     * @param int    $idNode id_node_translate индефикаторо который связан с таблицой даннных.
     * @param array  $dataTranslate данные для записи в таблицу переводов, масив может содержать и лишние данные,
     *                              нужные данные будут собранны автоматически
     * @param string|null $lang язык для которого происходит обновление, если не указан устанавливается текущий
     * @return void
     */
    public function updateTranslate ($tableBase, $idNode, $dataTranslate, $lang = null)
    {
        $tt = $tableBase . $this->_prefix_translate;
        if ($lang === null) {
            $lang = Arm_Translate::getInstance()->getLanguage();
        }
        $idLang = Arm_Translate::getInstance()->getIdLang($lang);
        $dataUpdate = $this->_getArrayColumTable($tt, $dataTranslate);
        if($dataUpdate === array()) {
            return;
        }
        // обновляем
        $this->getDb()->update($tt, $dataUpdate, 'id_node_translate=' . $idNode);
        return;
    }
    
    /**
     * Создания таблици с переводами.
     * @param string $tableBase базовая таблица
     * @param array $field поля которые нужно создать, можно создавать поля
     *                     типа v - varchar t - text 
     *              <code>
     *              $field = array();
      $field[]= array('name'=>'title', 'type'=>'varchar', 'len'>255);
      $field[] = array('name'=>'body', 'type'=>'text');
     *              </code>
     * @return void
     */
    public function createTableTranslate($tableBase, array $field=array())
    {
        $tableBase = strtolower($tableBase);
       // проверим существует ли базовая таблица
       $tables = $this->getDb()->listTables();
       foreach ($tables as $k=>$v) {
           $tables[$k] = strtolower($v);
       }
       if(false === array_search($tableBase, $tables)) {
           throw new Arm_Translate_Exception(Arm_Translate::_('Не существует базовой таблици: %s', $tableBase));
       }
       // Проверим возмо есть уже таблица с переводами
       $tt = $this->getNameTableTranslate($tableBase);
        if(false !== array_search($tt, $tables)) {
           throw new Arm_Translate_Exception(Arm_Translate::_('Уже есть таблица переводов в базе: %s', $tt));
       }
       // создаем базовую таблицу
       $sql = file_get_contents(dirname(__FILE__) . '/table_translate.sql');
       $sql = str_replace('{NAME_TABLE}', $tt, $sql);
       $this->getDb()->query($sql);
       // создаем поля
       $sqlVarchar = "ALTER TABLE `$tt` ADD `#name#` VARCHAR( #len# ) NULL  COMMENT '#coment#'"; 
       $sqlText    = "ALTER TABLE `$tt` ADD `#name#` TEXT NULL  COMMENT '#coment#'";
       foreach ($field as $k=>$v) {
           if(false === array_key_exists('name', $v)) {
               throw new Arm_Translate_Exception(Arm_Translate::_('Вы не укзали ключ name, для создания поля, данные: %s', print_r($v, true)));
           }
           if(false === array_key_exists('type', $v)) {
               $v['type'] = 'varchar';
           }
           if(false === array_key_exists('len', $v)) {
               $v['len'] = 255;
           }
       if(false === array_key_exists('coment', $v)) {
               $v['coment'] = 'no coment';
           }
           $searsh = array();
           $replace = array();
           // делаем масивы для поиска и замены
           foreach ($v as $s=>$r) {
               $searsh[] = '#' . $s . '#';
               $replace[] = $r;
           }
           if($v['type'] === 'varchar') {
               $sql = str_replace($searsh, $replace, $sqlVarchar);
               $this->getDb()->query($sql);
           } else {
               $sql = str_replace($searsh, $replace, $sqlText);
               $this->getDb()->query($sql);
           }
       } 
        // ALTER TABLE `test` ADD `dfdsf` VARCHAR( 12 ) NULL  COMMENT 'sdf'
        
    }
}